package edu.sjtu.grid.workflow.test;

import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import edu.sjtu.grid.workflow.Util;
import edu.sjtu.grid.workflow.facts.Facts;
import edu.sjtu.grid.workflow.facts.Run;

public class Analysis1 {
	public static void main(String[] args) {
		
		String s = "";
		s += analysis("facts/Epigenomics_24/facts.xml");
		s += analysis("facts/Inspiral_30/facts.xml");
		s += analysis("facts/Montage_25/facts.xml");
		s += analysis("facts/CyberShake_30/facts.xml");
		
		//analysis("facts/Epigenomics_46/facts.xml");
		//analysis("facts/Inspiral_50/facts.xml");//??
		//analysis("facts/Montage_50/facts.xml");//??
		//analysis("facts/CyberShake_50/facts.xml");

		Util.saveToNewFile(".\\result.csv", s);
	}
	
	public static String analysis(String file) {	
		Facts f = new Facts();
		f.loadXmlFile(file);
		Run cheapest = f.getRuns().getCheapestRun();
		Run heft = f.getRuns().getHEFTRun();
		if(cheapest == null || heft == null)
			return "";
		double cheapestCost = cheapest.getCost();
		double fastestMakespan = heft.getMakespan();
		String print = file + "\r\n";
		//s +="==HeuristicSearch==\r\n";
		//s += helper(f.getRuns().getHeuristicSearchRunList(), fastestMakespan, cheapestCost);
		print +="\r\n==HeuristicSearch_AvgCost==\r\n";
		print += helper_print(f.getRuns().getHeuristicSearchRunList_AvgCost(), fastestMakespan, cheapestCost);
		print +="\r\n==HeuristicSearch_AvgCost_Wait==\r\n";
		print += helper_print(f.getRuns().getHeuristicSearchRunList_AvgCost_Wait(), fastestMakespan, cheapestCost);
		//s +="==HeuristicSearch_InitialCost==\r\n";
		//s += helper(f.getRuns().getHeuristicSearchRunList_InitialCost(), fastestMakespan, cheapestCost);
		print += "\r\n==MDPSearch==\r\n";
		print += helper_print(f.getRuns().getMDPSearchRunList(), fastestMakespan, cheapestCost);
		System.out.println(print);
		
		Set<Double> deadlineSet = new HashSet<Double>();
		Map<Double, Double> avgCost_cost = new HashMap<Double, Double>();
		Map<Double, Double> avgCost_runtime = new HashMap<Double, Double>();
		Map<Double, Double> wait_cost = new HashMap<Double, Double>();
		Map<Double, Double> wait_runtime = new HashMap<Double, Double>();
		Map<Double, Double> mdp_cost = new HashMap<Double, Double>();
		Map<Double, Double> mdp_runtime = new HashMap<Double, Double>();
		for(Run run : f.getRuns().getHeuristicSearchRunList_AvgCost())
		{
			deadlineSet.add(run.getDeadline());
			if(run.isSucc())
			{
				avgCost_cost.put(run.getDeadline(), run.getCost());
				avgCost_runtime.put(run.getDeadline(), run.getRuntime());
			}
		}
		for(Run run : f.getRuns().getHeuristicSearchRunList_AvgCost_Wait())
		{
			deadlineSet.add(run.getDeadline());
			if(run.isSucc())
			{
				wait_cost.put(run.getDeadline(), run.getCost());
				wait_runtime.put(run.getDeadline(), run.getRuntime());
			}
		}
		for(Run run : f.getRuns().getMDPSearchRunList())
		{
			deadlineSet.add(run.getDeadline());
			if(run.isSucc())
			{
				mdp_cost.put(run.getDeadline(), run.getCost());
				mdp_runtime.put(run.getDeadline(), run.getRuntime());
			}
		}
		Double deadlineArray[] = new Double[deadlineSet.size()];
		deadlineSet.toArray(deadlineArray);
		Arrays.sort(deadlineArray);
		
		String save = file + ",,,,,,\r\n";
		save += "factor," + "AvgCost_cost,AvgCost_runtime," + "AvgCost_Wait_cost,AvgCost_Wait_runtime," + "MDPSearch_cost,MDPSearch_runtime," + "\r\n";
		for(Double d : deadlineArray)
		{
			save += Util.formatOutputDouble(d/fastestMakespan, "0.#") + ",";
			
			if(avgCost_cost.containsKey(d))
			{
				save += Util.formatOutputDouble(avgCost_cost.get(d) / cheapestCost, "0.######") + ",";
				save += Util.formatOutputDouble(avgCost_runtime.get(d), "#.########") + ",";
			}
			else
				save += ",,";
			
			if(wait_cost.containsKey(d))
			{
				save += Util.formatOutputDouble(wait_cost.get(d) / cheapestCost, "0.######") + ",";
				save += Util.formatOutputDouble(wait_runtime.get(d), "#.########") + ",";
			}
			else
				save += ",,";
			
			if(mdp_cost.containsKey(d))
			{
				save += Util.formatOutputDouble(mdp_cost.get(d) / cheapestCost, "0.######") + ",";
				save += Util.formatOutputDouble(mdp_runtime.get(d), "#.########") + ",";
			}
			else
				save += ",,";
			save += "\r\n";
		}
		
		//Util.saveToNewFile(".\\result.csv", save);
		return save;
	}
	
	private static String helper_print(List<Run> runList, double fastestMakespan, double cheapestCost)
	{
		String s = "factor\tmakespan\truntime\r\n";
		for(Run run : runList)
		{
			s += Util.formatOutputDouble(run.getDeadline()/fastestMakespan, "0.#", 2);
			if(run.isSucc())
			{
				s += Util.formatOutputDouble(run.getCost() / cheapestCost, "0.######", 2);
				s += Util.formatOutputDouble(run.getRuntime(), "0.########")+ "\r\n";
			}
			else
				s += "failed\r\n";
		}
		/*s += "--cost--\r\n";
		for(Run run : runList)
		{
			if(run.isSucc())
				s += Util.formatOutputDouble(run.getCost() / cheapestCost, "0.######") + "\r\n";
			else
				s += "failed\r\n";
		}
		s += "--runtime--\r\n";
		for(Run run : runList)
		{
			s += Util.formatOutputDouble(run.getRuntime(), "0.########") + "\r\n";
		}*/
		return s;
	}
}